/**
 * 
 */
package edu.ust.seis610.utils;

import java.util.HashMap;
import java.util.Random;

import edu.ust.seis610.function.Function;
import edu.ust.seis610.function.TreeElement;

/**
 * @author meeusen
 *
 */
@SuppressWarnings({"unchecked","rawtypes"})
public class NodeUtils
{

//	there are four types of possible operators
	public static Enum getRandomOperator() 
	{
//		just set tmp =DIVIDE for init value so this compiles the default clause will make things OK if the switch bombs
		Enum tmp=TreeElement.Operator.DIVIDE;
		Random rand = new Random();
		int x = rand.nextInt(4);
		
		switch (x)
		{
			case 0:
				tmp = TreeElement.Operator.DIVIDE;
				break;
			case 1:
				tmp = TreeElement.Operator.MINUS;
				break;
			case 2:
				tmp = TreeElement.Operator.MULTIPLY;
				break;
			case 3:
				tmp = TreeElement.Operator.PLUS;
				break;
		}
		return tmp;
	}
	
//	there are ten types of possible operands
	public static Enum getRandomOperand() 
	{
		
//		set tmp to a trival enum type the switch stmt below will set it to a random operand enum type
		Enum tmp=TreeElement.Operand.EIGHT;
		Random rand = new Random();
		int x = rand.nextInt(11);
		
		switch (x)
		{
			case 0:
				tmp = TreeElement.Operand.ZERO;
				break;
			case 1:
				tmp = TreeElement.Operand.ONE;
				break;
			case 2:
				tmp = TreeElement.Operand.TWO;
				break;
			case 3:
				tmp = TreeElement.Operand.THREE;
				break;
			case 4:
				tmp = TreeElement.Operand.FOUR;
				break;
			case 5:
				tmp = TreeElement.Operand.FIVE;
				break;
			case 6:
				tmp = TreeElement.Operand.SIX;
				break;
			case 7:
				tmp = TreeElement.Operand.SEVEN;
				break;
			case 8:
				tmp = TreeElement.Operand.EIGHT;
				break;
			case 9:
				tmp = TreeElement.Operand.NINE;
				break;
			case 10:
				tmp = TreeElement.Operand.X;
				break;
		}
		return tmp;
		
	}
	
	
	public static void mutateFunction(Function aFunc) 
	{
		Random rand = new Random();
		int x = rand.nextInt(2);
		int y;
		
		switch(x)
		{
			case 0:
			{
//				this gens a random number 0-3 and then replaces the operator key/value at that pos
				y = rand.nextInt(3);
				aFunc.getEquationMap().put("y"+(y+1), NodeUtils.getRandomOperator());
			}
			break;
			case 1:
			{
//				put logic to replace random operand
				y=rand.nextInt(4);
				aFunc.getEquationMap().put("z"+(y+1), NodeUtils.getRandomOperand());
			}
			break;
		}
	}
	
	public static void crossoverFunctions(Function funcA, Function funcB)
	{
		HashMap tmpA = new HashMap();
		HashMap tmpB = new HashMap();
		
//		put the inner most function to the temp maps
		tmpA.put("z1", funcA.getEquationMap().get("z1"));
		tmpA.put("z2", funcA.getEquationMap().get("z2"));
		tmpA.put("y1", funcA.getEquationMap().get("y1"));
		tmpB.put("z1", funcB.getEquationMap().get("z1"));
		tmpB.put("z2", funcB.getEquationMap().get("z2"));
		tmpB.put("y1", funcB.getEquationMap().get("y1"));
		
//		now dump the key/values from the opposite temp maps to the original functions.  
//		This effectively does the crossover.
		funcA.getEquationMap().putAll(tmpB);
		funcB.getEquationMap().putAll(tmpA);
	}
}
